/*----------------------------------------------------------------------*
 *	CLASS:	Qt3ClassicalBoardImpl
 *	Quantum Tic Tac Toe
 *	Copyright (c) 2005-2009 Novatia Labs, Inc.  All rights reserved.
 *----------------------------------------------------------------------*/

package com.novatialabs.qttt.engine.impl;

import com.novatialabs.qttt.engine.Qt3ClassicalBoard;
import com.novatialabs.qttt.engine.Qt3Player;

/**
 * Qt3Game defines the interface to a game of Quantum Tic Tac Toe.
 *
 * Warning: It is important that this class remain immutable so that 
 * classic boards in previous state are not modified.
 *
 * @Author	Duane Gibson
 * @Author Friendly development resources cheerfully provided by Charles Phares.
 * @Author	$Author$
 * @Version	$Revision$
 */

public class Qt3ClassicalBoardImpl
    implements Qt3ClassicalBoard
{

    private Qt3ClassicalSquareImpl[]	board;


   /*-------------------------------------------------------------------*
    *	CONSTRUCTOR:	Qt3ClassicalBoardImpl()
    *	AUTHOR:		Duane Gibson
    *	CREATION DATE:	Mon Jan 10 21:32:05 PST 2005
    *-------------------------------------------------------------------*/
   /**
    * Constructs an empty classical board.
    * Returns the constant Qt3Player.X if there is an "X" in the square.
    * Returns the constant Qt3Player.O if there is an "O" in the square.
    * Returns null if the square is empty.
    *
    * @throws IllegalArgumentException
    *	if the square number is &lt; 1 or &gt; 9.
    */

    /*package*/ Qt3ClassicalBoardImpl()
    {

	final Qt3ClassicalSquareImpl[] myBoard = new Qt3ClassicalSquareImpl[9];
	// for ( int index = 0 ; index < 9 ; ++index ) {
	//    myBoard[index] = null;
	// }
	this.board = myBoard;

    } // Qt3ClassicalBoardImpl()

   /*-------------------------------------------------------------------*
    *	METHOD:		getPlayerInSquare()
    *	AUTHOR:		Duane Gibson
    *	CREATION DATE:	Mon Jan 10 21:30:22 PST 2005
    *-------------------------------------------------------------------*/
   /**
    * Returns the "owner" of the specified square.
    * Returns the constant Qt3Player.X if there is an "X" in the square.
    * Returns the constant Qt3Player.O if there is an "O" in the square.
    * Returns null if the square is empty.
    *
    * @throws IllegalArgumentException
    *	if the square number is &lt; 1 or &gt; 9.
    */

    public Qt3Player getPlayerInSquare(
	int	squareNumber	// number of the square (1-9)
	)
	throws IllegalArgumentException
    {

	if ( (squareNumber < 1) || (squareNumber > 9) ) {
	    throw new IllegalArgumentException();
	}

	return this.getPlayerAtSquareIndex(squareNumber-1);
    } // getPlayerInSquare()

   /*-------------------------------------------------------------------*
    *	METHOD:		getPlayerAtSquareIndex()
    *	AUTHOR:		Duane Gibson
    *	CREATION DATE:	Mon Jan 10 21:30:22 PST 2005
    *-------------------------------------------------------------------*/
   /**
    * Returns the "owner" of the specified square.
    * Returns the constant Qt3Player.X if there is an "X" in the square.
    * Returns the constant Qt3Player.O if there is an "O" in the square.
    * Returns null if the square is empty.
    *
    * @throws ArrayIndexOutOfBoundsException
    *	if the square index is &lt; 0 or &gt; 8.
    */

    /*package*/ Qt3Player getPlayerAtSquareIndex(
	int	squareIndex	// index of the square (0-8)
	)
	throws ArrayIndexOutOfBoundsException
    {
	Qt3ClassicalSquareImpl square = this.board[squareIndex];

	if ( square == null ) {
	    return null;
	}

	return square.getPlayer();

    } // getPlayerAtSquareIndex()

   /*-------------------------------------------------------------------*
    *	METHOD:		getMoveAtSquareIndex()
    *	AUTHOR:		Duane Gibson
    *	CREATION DATE:	Thu Apr  6 20:31:29 PDT 2006
    *-------------------------------------------------------------------*/
   /**
    * Returns the move in which the specified square was taken.
    * Returns -1 if the square has not been moved in yet.
    *
    * @throws ArrayIndexOutOfBoundsException
    *	if the square index is &lt; 0 or &gt; 8.
    */

    /*package*/ int getMoveAtSquareIndex(
	int	squareIndex	// index of the square (0-8)
	)
	throws ArrayIndexOutOfBoundsException
    {
	Qt3ClassicalSquareImpl square = this.board[squareIndex];

	if ( square == null ) {
	    return -1;
	}

	return square.getMove();

    } // getPlayerAtSquareIndex()

   /*-------------------------------------------------------------------*
    *	METHOD:		addMove()
    *	AUTHOR:		Duane Gibson
    *	CREATION DATE:	Wed Feb  9 19:56:30 PST 2005
    *-------------------------------------------------------------------*/
   /**
    * adds the specified player at the given square index.
    *
    * @param moveNumber		the number of the move.
    * @param movingPlayer	the player making the move.
    * @param squareIndex	the index of the square.
    * @throws NullPointerException
    *	if the player is null
    * @throws ArrayIndexOutOfBoundsException
    *	if the square index is &lt; 0 or &gt; 8.
    */

    /*package*/ void addMove(
	int		moveNumber,
	Qt3Player	movingPlayer,
	int		squareIndex	// index of square (0-8)
	)
    {

	if ( movingPlayer == null ) {
	    throw new NullPointerException();
	}

	this.board[squareIndex] = new Qt3ClassicalSquareImpl(
						movingPlayer, moveNumber);

    }  // addMove()

   /*-------------------------------------------------------------------*
    *	METHOD:		cloneAndAddMove()
    *	AUTHOR:		Duane Gibson
    *	CREATION DATE:	Mon Jan 10 21:54:53 PST 2005
    *-------------------------------------------------------------------*/
   /**
    * Clones the current classical board and adds the specified player
    * at the given square index.
    *
    * @param moveNumber		the number of the move.
    * @param movingPlayer	the player making the move.
    * @param squareIndex	the index of the square.
    * @throws NullPointerException
    *	if the player is null
    * @throws ArrayIndexOutOfBoundsException
    *	if the square index is &lt; 0 or &gt; 8.
    */

    /*package*/ Qt3ClassicalBoardImpl cloneAndAddMove(
	int		moveNumber,
	Qt3Player	movingPlayer,
	int		squareIndex	// index of square (0-8)
	)
    {

	Qt3ClassicalBoardImpl clone = new Qt3ClassicalBoardImpl();

	for ( int index = 0 ; index < 9 ; ++index ) {
	    clone.board[index] = this.board[index];
	}

	clone.addMove(moveNumber, movingPlayer, squareIndex);

	return clone;

    }  // cloneAndAddMove()


   /*-------------------------------------------------------------------*
    *	CLASS:		Qt3ClassicalSquareImpl
    *	AUTHOR:		Duane Gibson
    *	CREATION DATE:	Thu Apr  6 20:06:34 PDT 2006
    *-------------------------------------------------------------------*/
   /**
    * Qt3ClassicalSquareImpl holds the state of a square on the classical
    * board.
    *
    * <p> Warning: It is important that this class remain immutable so
    * that classic boards in previous state are not modified.
    */

    private class Qt3ClassicalSquareImpl
    {

	private Qt3Player	owningPlayer;
	private int		owningMove;

       /*-------------------------------------------------------------------*
	*	CONSTRUCTOR:	Qt3ClassicalSquareImpl
	*	AUTHOR:		Duane Gibson
	*	CREATION DATE:	Thu Apr  6 20:08:13 PDT 2006
	*-------------------------------------------------------------------*/
       /**
	* Constructs a Qt3ClassicalSquareImpl.
	*
	* @param player		the player that moved in this square.
	* @param moveNumber	the move that was placed in this square.
	*/

	private Qt3ClassicalSquareImpl(
		Qt3Player player,
		int       moveNumber
		)
	{
	    this.owningPlayer = player;
	    this.owningMove = moveNumber;
	}

       /*-------------------------------------------------------------------*
	*	METHOD:		getPlayer
	*	AUTHOR:		Duane Gibson
	*	CREATION DATE:	Thu Apr  6 20:19:25 PDT 2006
	*-------------------------------------------------------------------*/
       /**
	* Returns player that moved in this square.
	*/

	public Qt3Player getPlayer()
	{
	    return this.owningPlayer;
	}

       /*-------------------------------------------------------------------*
	*	METHOD:		getMove
	*	AUTHOR:		Duane Gibson
	*	CREATION DATE:	Thu Apr  6 20:20:01 PDT 2006
	*-------------------------------------------------------------------*/
       /**
	* Returns the move that was placed in this square.
	*/

	public int getMove()
	{
	    return this.owningMove;
	}

    } // class Qt3ClassicalBoardImpl

} // class Qt3ClassicalBoardImpl

